/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package requestManager;

import app.Global;
import app.MyController;
import app.MyView;
import entities.EmployeeShiftRequest;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;

/**
 *
 * @author yoshi
 */
public class RequestManagerController implements MyController {

    private long departmentId;
    private AbstractRequestManager myView;

    RequestManagerController(long departmentId) {
        this.departmentId = departmentId;
    }

    @Override
    public AbstractRequestManager getMyView() {
        return myView;
    }

    @Override
    public RequestManagerModel getMyModel() {
        return this.getMyView().getMyModel();
    }

    /*
     * Function to approve the request
     * 
     */
    public void approve(EmployeeShiftRequest request) {
        Connection connection = Global.getConnection();
        PreparedStatement pst = null;
        ResultSet rs = null;

        String query = Global.getRequestQuery() + " WHERE esr.id = ? AND esr.status = 2";
        try {
            pst = connection.prepareStatement(query);
            pst.setLong(1, request.getId());
            rs = pst.executeQuery();

            if (rs.next()) {
                request.loadFromResultSet(rs);
            } else {
                JOptionPane.showMessageDialog(this.getMyView(), "There's something wrong, maybe the data is updated from other people", "Approve error", JOptionPane.ERROR_MESSAGE);
                return;
            }

            if (!Global.getAuth().isDepartmentHead() || !Global.getAuth().isManager()) {
                JOptionPane.showMessageDialog(this.getMyView(), "You don't have permission to approve request");
            } else if (request.getFromSchedule().getEmployee().getRoll().isHead() && !Global.getAuth().isManager()) {
                JOptionPane.showMessageDialog(this.getMyView(), "You don't have permission to approve request of department heads");
            } else if (!request.getFromSchedule().getEmployee().getRoll().isHead()
                    && (!Global.getAuth().isDepartmentHead() || request.getEmployee().getDepartmentId() != Global.getAuth().getDepartmentId())) {
                JOptionPane.showMessageDialog(this.getMyView(), "You don't have permission to approve request in this department");
            } else if (request.getFromSchedule().getEmployee().getId() == Global.getAuth().getId() || request.getEmployee().getId() == Global.getAuth().getId()) {
                JOptionPane.showMessageDialog(this.getMyView(), "You can not approve the request of yours");
            } else if (request.getFromSchedule().getEmployeeId() == request.getEmployeeId()) {
                JOptionPane.showMessageDialog(this.getMyView(), "Can't shift same employee schedules");
            } else if (request.getEmployee() == null || request.getEmployee().getId() == 0) {
                JOptionPane.showMessageDialog(this.getMyView(), "Don't have anyone to change now");
            } else if (request.getStatus() == 0) {
                JOptionPane.showMessageDialog(this.getMyView(), "The request was disapproved");
            } else if (request.getStatus() == 1) {
                JOptionPane.showMessageDialog(this.getMyView(), "Don't have anyone to change now");
            } else if (request.getStatus() == 3) {
                JOptionPane.showMessageDialog(this.getMyView(), "The request was approved");
            } else {
                // update 2 schedules status to inactive
                String q1 = "UPDATE employee_schedules SET status = 0 WHERE id = ?";
                String q2 = "UPDATE employee_schedules SET status = 0 WHERE employee_id = ? AND date = ? AND time_slot_id = ?";

                // update the request status to approved
                String q3 = "UPDATE employee_shift_requests SET status = 3 WHERE id = ?";

                // insert two records swap user schedules
                String q4 = "INSERT INTO employee_schedules(employee_id, date, time_slot_id, status, created, modified) VALUES(?, ?, ?, ?, ?, ?)";

                connection.setAutoCommit(false);

                pst = connection.prepareStatement(q1);
                pst.setLong(1, request.getFromScheduleId());
                pst.setLong(2, request.getEmployeeId());
                pst.executeUpdate();
                pst.close();
                
                pst = connection.prepareStatement(q2);
                pst.setLong(1, request.getEmployeeId());
                pst.setDate(2, request.getRequestDate());
                pst.setLong(3, request.getTimeSlotId());
                pst.executeUpdate();
                pst.close();

                pst = connection.prepareStatement(q3);
                pst.setLong(1, request.getId());
                pst.executeUpdate();
                pst.close();

                Date now = new Date(new java.util.Date().getTime());
                pst = connection.prepareStatement(q4);
                pst.setLong(1, request.getFromSchedule().getEmployeeId());
                pst.setDate(2, request.getRequestDate());
                pst.setLong(3, request.getTimeSlotId());
                pst.setInt(4, 1);
                pst.setDate(5, now);
                pst.setDate(6, now);
                pst.addBatch();

                pst.setLong(1, request.getEmployeeId());
                pst.setDate(2, request.getFromSchedule().getDate());
                pst.setLong(3, request.getFromSchedule().getTimeSlotId());
                pst.addBatch();
                pst.close();

                pst.executeBatch();
                connection.commit();
            }
        } catch (SQLException ex) {
            Logger.getLogger(RequestManagerController.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                rs.close();
                pst.close();
                connection.close();
            } catch (SQLException ex) {
                Logger.getLogger(RequestManagerController.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                this.getMyView().refresh();
            }
        }
    }

    /*
     * Function to disapprove the request
     * 
     */
    public void disapprove(EmployeeShiftRequest request) {
        Connection connection = Global.getConnection();
        PreparedStatement pst = null;
        try {
            pst = connection.prepareStatement("UPDATE employee_shift_requests SET status =  0 WHERE id = ?");
            pst.setLong(1, request.getId());
            pst.executeUpdate();
        } catch (SQLException ex) {
            Logger.getLogger(RequestManagerController.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                pst.close();
                connection.close();
            } catch (SQLException ex) {
                Logger.getLogger(RequestManagerController.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                this.getMyView().refresh();
            }
        }
    }

    /*
     * Function to accept change with request
     * 
     */
    public void acceptChange(EmployeeShiftRequest request) {
        Connection connection = Global.getConnection();
        PreparedStatement pst = null;
        ResultSet rs = null;
        try {
            pst = connection.prepareStatement(Global.getRequestQuery() + " WHERE esr.id = ? AND esr.status = 1");
            pst.setLong(1, request.getId());
            rs = pst.executeQuery();
            if (rs.next()) {
                request.loadFromResultSet(rs);
            } else {
                JOptionPane.showMessageDialog(this.getMyView(), "There's something wrong, maybe the request is updated from other people", "Accept error", JOptionPane.ERROR_MESSAGE);
                return;
            }
            pst.close();

            if (Global.getAuth().isManager()) {
                JOptionPane.showMessageDialog(this.getMyView(), "You're manager?", "Accept change error", JOptionPane.ERROR_MESSAGE);
            } else if (Global.getAuth().getDepartmentId() != request.getEmployee().getDepartmentId()) {
                JOptionPane.showMessageDialog(this.getMyView(), "Can not change with employee from other department", "Accept change error", JOptionPane.ERROR_MESSAGE);
            } else if (Global.getAuth().isDepartmentHead() && !request.getEmployee().isDepartmentHead()) {
                JOptionPane.showMessageDialog(this.getMyView(), "Can not change with other role", "Accept change error", JOptionPane.ERROR_MESSAGE);
            } else if (!Global.getAuth().isDepartmentHead() && request.getEmployee().isDepartmentHead()) {
                JOptionPane.showMessageDialog(this.getMyView(), "Can not change with other role", "Accept change error", JOptionPane.ERROR_MESSAGE);
            } else {
                pst = connection.prepareStatement("SELECT TOP 1 id FROM employee_schedules WHERE date = ? AND employee_id = ? AND time_slot_id = ? AND status = 1");
                pst.setDate(1, request.getRequestDate());
                pst.setLong(2, Global.getAuth().getId());
                pst.setLong(3, request.getTimeSlotId());
                if (!pst.executeQuery().next()) {
                    JOptionPane.showMessageDialog(this.getMyView(), "You don't have schedule in request time slot", "Accept error", JOptionPane.ERROR_MESSAGE);
                    return;
                }
                pst.close();

                pst.setDate(1, request.getFromSchedule().getDate());
                pst.setLong(2, Global.getAuth().getId());
                pst.setLong(3, request.getFromSchedule().getTimeSlotId());
                if (pst.executeQuery().next()) {
                    JOptionPane.showMessageDialog(this.getMyView(), "You've already had schedule in changed time", "Accept error", JOptionPane.ERROR_MESSAGE);
                    return;
                }
                pst.close();

                pst = connection.prepareStatement("UPDATE employee_shift_requests SET employee_id = ? AND status = 2");
                pst.setLong(1, request.getId());
                pst.executeUpdate();
            }
        } catch (SQLException ex) {
            Logger.getLogger(RequestManagerController.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                rs.close();
                pst.close();
                connection.close();
            } catch (SQLException ex) {
                Logger.getLogger(RequestManagerController.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                this.getMyView().refresh();
            }
        }
    }

    @Override
    public void setMyView(MyView myView) {
        this.myView = (AbstractRequestManager) myView;
    }
}
